package com.chat.netty.handler;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

/**
 * @version V1.0
 * @Title:
 * @Package
 * @Description:
 * @author: 刘星星
 * @date: 2020/4/22 15:32
 */
@Component
@Scope("prototype")
public class WSServerSocketChannel extends ChannelInitializer<SocketChannel> {

    @Autowired
    BeanFactory beanFactory;

    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        // 获取处理通道
        ChannelPipeline cp = socketChannel.pipeline();

        // websocket 基于http协议，所以要有http编解码器
        cp.addLast(new HttpServerCodec());
        // 添加对大数据流的支持
        cp.addLast(new ChunkedWriteHandler());
        // 对httpMessage进行聚合，聚合成FullHttpRequest或FullHttpResponse
        // 几乎在netty中的编程，都会使用到此hanler
        cp.addLast(new HttpObjectAggregator(1024*64));
        // ====================== 以上是用于支持http协议    ======================

        // ====================== 以下是支持httpWebsocket ======================
        /**
         * websocket 服务器处理的协议，用于指定给客户端连接访问的路由 : /ws
         * 本handler会帮你处理一些繁重的复杂的事
         * 会帮你处理握手动作： handshaking（close, ping, pong） ping + pong = 心跳
         * 对于websocket来讲，都是以frames进行传输的，不同的数据类型对应的frames也不同
         */
        cp.addLast(new WebSocketServerProtocolHandler("/ws"));
        // 自定义处理
        ChatHandler chatHandler = beanFactory.getBean(ChatHandler.class);
        cp.addLast(chatHandler);
    }
}
